---
title: Camera (legacy)
description: A React component that renders a preview for the device's front or back camera.
sourceCodeUrl: 'https://github.com/expo/expo/tree/main/packages/expo-camera'
packageName: 'expo-camera'
iconUrl: '/static/images/packages/expo-camera.png'
platforms: ['android*', 'ios*', 'web']
---

import APISection from '~/components/plugins/APISection';
import { APIInstallSection } from '~/components/plugins/InstallSection';
import { AndroidPermissions, IOSPermissions } from '~/components/plugins/permissions';
import {
  ConfigReactNative,
  ConfigPluginExample,
  ConfigPluginProperties,
} from '~/ui/components/ConfigSection';
import { SnackInline } from '~/ui/components/Snippet';

> **warning** This is the legacy version of the `expo-camera` package which will no longer be receiving updates. If you are starting a new project, we recommend using [the latest version of `expo-camera`](/versions/v51.0.0/sdk/camera).

`expo-camera` provides a React component that renders a preview of the device's front or back camera. The camera's parameters such as zoom, auto focus, white balance and flash mode are adjustable. Using `Camera`, you can take photos and record videos that are saved to the app's cache. The component is also capable of detecting faces and bar codes appearing in the preview. Run the [example](#usage) on your device to see all these features working together.

> **info** Android devices can use one of two available Camera APIs: you can opt-in to using [`Camera2`](https://developer.android.com/reference/android/hardware/camera2/package-summary) with the `useCamera2Api` prop.

## Installation

<APIInstallSection />

## Configuration in app.json/app.config.js

You can configure `expo-camera` using its built-in [config plugin](/config-plugins/introduction/) if you use config plugins in your project ([EAS Build](/build/introduction) or `npx expo run:[android|ios]`). The plugin allows you to configure various properties that cannot be set at runtime and require building a new app binary to take effect.

<ConfigPluginExample>

```json app.json
{
  "expo": {
    "plugins": [
      [
        "expo-camera",
        {
          "cameraPermission": "Allow $(PRODUCT_NAME) to access your camera",
          "microphonePermission": "Allow $(PRODUCT_NAME) to access your microphone",
          "recordAudioAndroid": true
        }
      ]
    ]
  }
}
```

</ConfigPluginExample>

<ConfigPluginProperties
  properties={[
    {
      name: 'cameraPermission',
      platform: 'ios',
      description: 'A string to set the [`NSCameraUsageDescription`](#ios) permission message.',
      default: '"Allow $(PRODUCT_NAME) to access your camera"',
    },
    {
      name: 'microphonePermission',
      platform: 'ios',
      description: 'A string to set the [`NSMicrophoneUsageDescription`](#ios) permission message.',
      default: '"Allow $(PRODUCT_NAME) to access your microphone"',
    },
    {
      name: 'recordAudioAndroid',
      platform: 'android',
      description:
        'A boolean that determines whether to enable the `RECORD_AUDIO` permission on Android.',
      default: 'true',
    },
  ]}
/>

<ConfigReactNative>

Learn how to configure the native projects in the [installation instructions in the `expo-camera` repository](https://github.com/expo/expo/tree/main/packages/expo-camera#installation-in-bare-react-native-projects).

</ConfigReactNative>

## Usage

> **warning** Only one Camera preview can be active at any given time. If you have multiple screens in your app, you should unmount `Camera` components whenever a screen is unfocused.

<SnackInline label='Basic Camera usage' dependencies={['expo-camera']}>

```jsx
import { Camera, CameraType } from 'expo-camera/legacy';
import { useState } from 'react';
import { Button, StyleSheet, Text, TouchableOpacity, View } from 'react-native';

export default function App() {
  const [type, setType] = useState(CameraType.back);
  const [permission, requestPermission] = Camera.useCameraPermissions();

  if (!permission) {
    // Camera permissions are still loading
    return <View />;
  }

  if (!permission.granted) {
    // Camera permissions are not granted yet
    return (
      <View style={styles.container}>
        <Text style={{ textAlign: 'center' }}>We need your permission to show the camera</Text>
        <Button onPress={requestPermission} title="grant permission" />
      </View>
    );
  }

  function toggleCameraType() {
    setType(current => (current === CameraType.back ? CameraType.front : CameraType.back));
  }

  return (
    <View style={styles.container}>
      <Camera style={styles.camera} type={type}>
        <View style={styles.buttonContainer}>
          <TouchableOpacity style={styles.button} onPress={toggleCameraType}>
            <Text style={styles.text}>Flip Camera</Text>
          </TouchableOpacity>
        </View>
      </Camera>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
  },
  camera: {
    flex: 1,
  },
  buttonContainer: {
    flex: 1,
    flexDirection: 'row',
    backgroundColor: 'transparent',
    margin: 64,
  },
  button: {
    flex: 1,
    alignSelf: 'flex-end',
    alignItems: 'center',
  },
  text: {
    fontSize: 24,
    fontWeight: 'bold',
    color: 'white',
  },
});
```

</SnackInline>

## Web support

Most browsers support a version of web camera functionality, you can check out the [web camera browser support here](https://caniuse.com/#feat=stream). Image URIs are always returned as base64 strings because local file system paths are unavailable in the browser.

### Chrome `iframe` usage

When using **Chrome versions 64+**, if you try to use a web camera in a cross-origin iframe nothing will render. To add support for cameras in your iframe simply add the attribute `allow="microphone; camera;"` to the iframe element:

```html
<iframe src="..." allow="microphone; camera;">
  <!-- <Camera /> -->
</iframe>
```

## API

```js
import { Camera } from 'expo-camera/legacy';
```

<APISection packageName="expo-camera-legacy" apiName="Camera" />

## Permissions

### Android

This package automatically adds the `CAMERA` permission to your app. If you want to record videos with audio, you have to include the `RECORD_AUDIO` in your **app.json** inside the [`expo.android.permissions`](/versions/latest/config/app/#permissions) array.

<AndroidPermissions permissions={['CAMERA', 'RECORD_AUDIO']} />

### iOS

The following usage description keys are used by this library:

<IOSPermissions permissions={['NSCameraUsageDescription', 'NSMicrophoneUsageDescription']} />
